﻿/********************************************************************
	created:	2011-8-12   7:20
	author:		Lifan Su
	
	purpose:	implement
*********************************************************************/

#include "cvt_int_mem.h"

#include <configure.h>


//  cvt_byte_to_uNN_be series
CVT_INT_MEM_PREFIX uint8_t CVT_INT_MEM_API cvt_byte_to_u08_be(const void *src)
{
    return *((const uint8_t *)src);
}

#if defined __BIG_ENDIAN__ && defined __NO_ALIGN_REQ__

CVT_INT_MEM_PREFIX uint16_t CVT_INT_MEM_API cvt_byte_to_u16_be(const void *src)
{
    return *((const uint16_t *)src);
}

CVT_INT_MEM_PREFIX uint32_t CVT_INT_MEM_API cvt_byte_to_u32_be(const void *src)
{
    return *((const uint32_t *)src);
}

CVT_INT_MEM_PREFIX uint64_t CVT_INT_MEM_API cvt_byte_to_u64_be(const void *src)
{
    return *((const uint32_t *)src);
}

#elif defined __LITTLE_ENDIAN__ && defined __NO_ALIGN_REQ__

CVT_INT_MEM_PREFIX uint16_t CVT_INT_MEM_API cvt_byte_to_u16_be(const void *src)
{
    return cvt_u16_endian(*((const uint16_t *)src));
}

CVT_INT_MEM_PREFIX uint32_t CVT_INT_MEM_API cvt_byte_to_u32_be(const void *src)
{
    return cvt_u32_endian(*((const uint32_t *)src));
}

CVT_INT_MEM_PREFIX uint64_t CVT_INT_MEM_API cvt_byte_to_u64_be(const void *src)
{
    uint64_t res;
    res = cvt_u64_endian(*((const uint64_t *)src));
    return res;
}

#else

CVT_INT_MEM_PREFIX uint16_t CVT_INT_MEM_API cvt_byte_to_u16_be(const void *src)
{
    uint16_t res = 0;
    const uint8_t *_src = src;
    
    res |= ((uint16_t)*(_src++)) << 8;
    res |= ((uint16_t)*_src);

    return res;
}

CVT_INT_MEM_PREFIX uint32_t CVT_INT_MEM_API cvt_byte_to_u32_be(const void *src)
{
    uint32_t res = 0;
    const uint8_t *_src = src;

    res |= ((uint32_t)*(_src++)) << 24;
    res |= ((uint32_t)*(_src++)) << 16;
    res |= ((uint32_t)*(_src++)) << 8;
    res |= ((uint32_t)*_src);

    return res;
}

CVT_INT_MEM_PREFIX uint64_t CVT_INT_MEM_API cvt_byte_to_u64_be(const void *src)
{
    uint64_t res = 0;
    const uint8_t *_src = src;

    res |= ((uint64_t)*(_src++)) << 56;
    res |= ((uint64_t)*(_src++)) << 48;
    res |= ((uint64_t)*(_src++)) << 40;
    res |= ((uint64_t)*(_src++)) << 32;
    res |= ((uint64_t)*(_src++)) << 24;
    res |= ((uint64_t)*(_src++)) << 16;
    res |= ((uint64_t)*(_src++)) << 8;
    res |= ((uint64_t)*_src);

    return res;
}

#endif


//  cvt_byte_to_uNN_le series
CVT_INT_MEM_PREFIX uint8_t  CVT_INT_MEM_API cvt_byte_to_u08_le(const void *src)
{
    return *((const uint8_t *)src);
}

#if defined __BIG_ENDIAN__ && defined __NO_ALIGN_REQ__

CVT_INT_MEM_PREFIX uint16_t CVT_INT_MEM_API cvt_byte_to_u16_le(const void *src)
{
    return cvt_u16_endian(*((const uint16_t *)src));
}

CVT_INT_MEM_PREFIX uint32_t CVT_INT_MEM_API cvt_byte_to_u32_le(const void *src)
{
    return cvt_u32_endian(*((const uint32_t *)src));
}

CVT_INT_MEM_PREFIX uint64_t CVT_INT_MEM_API cvt_byte_to_u64_le(const void *src)
{
    return cvt_u64_endian(*((const uint64_t *)src));
}

#elif defined __LITTLE_ENDIAN__ && defined __NO_ALIGN_REQ__

CVT_INT_MEM_PREFIX uint16_t CVT_INT_MEM_API cvt_byte_to_u16_le(const void *src)
{
    return *((const uint16_t *)src);
}

CVT_INT_MEM_PREFIX uint32_t CVT_INT_MEM_API cvt_byte_to_u32_le(const void *src)
{
    return *((const uint32_t *)src);
}

CVT_INT_MEM_PREFIX uint64_t CVT_INT_MEM_API cvt_byte_to_u64_le(const void *src)
{
    return *((const uint64_t *)src);
}

#else

CVT_INT_MEM_PREFIX uint16_t CVT_INT_MEM_API cvt_byte_to_u16_le(const void *src)
{
    uint16_t res = 0;
    const uint8_t *_src = src;

    res |= ((uint16_t)*(_src++));
    res |= ((uint16_t)*_src) << 8;

    return res;
}

CVT_INT_MEM_PREFIX uint32_t CVT_INT_MEM_API cvt_byte_to_u32_le(const void *src)
{
    uint32_t res = 0;
    const uint8_t *_src = src;

    res |= ((uint32_t)*(_src++));
    res |= ((uint32_t)*(_src++)) << 8;
    res |= ((uint32_t)*(_src++)) << 16;
    res |= ((uint32_t)*_src) << 24;

    return res;
}

CVT_INT_MEM_PREFIX uint64_t CVT_INT_MEM_API cvt_byte_to_u64_le(const void *src)
{
    uint64_t res = 0;
    const uint8_t *_src = src;

    res |= ((uint64_t)*(_src++)) << 56;
    res |= ((uint64_t)*(_src++)) << 48;
    res |= ((uint64_t)*(_src++)) << 40;
    res |= ((uint64_t)*(_src++)) << 32;
    res |= ((uint64_t)*(_src++)) << 24;
    res |= ((uint64_t)*(_src++)) << 16;
    res |= ((uint64_t)*(_src++)) << 8;
    res |= ((uint64_t)*_src);

    return res;
}

#endif


//  cvt_uNN_be_to_byte series
CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u08_be_to_byte(void *dst, uint8_t src)
{
    *((uint8_t *)dst) = src;
}

#if defined __BIG_ENDIAN__ && defined __NO_ALIGN_REQ__

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u16_be_to_byte(void *dst, uint16_t src)
{
    *((uint16_t)dst) = src;
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u32_be_to_byte(void *dst, uint32_t src)
{
    *((uint32_t)dst) = src;
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u64_be_to_byte(void *dst, uint64_t src)
{
    *((uint64_t)dst) = src;
}

#elif defined __LITTLE_ENDIAN__ && defined __NO_ALIGN_REQ__

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u16_be_to_byte(void *dst, uint16_t src)
{
    *((uint16_t *)dst) = cvt_u16_endian(src);
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u32_be_to_byte(void *dst, uint32_t src)
{
    *((uint32_t *)dst) = cvt_u32_endian(src);
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u64_be_to_byte(void *dst, uint64_t src)
{
    *((uint64_t *)dst) = cvt_u64_endian(src);
}

#else

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u16_be_to_byte(void *dst, uint16_t src)
{
    uint8_t *_dst = dst;
    *(dst++) = src >> 8;
    *dst = src;
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u32_be_to_byte(void *dst, uint32_t src)
{
    uint8_t *_dst = dst;
    *(dst++) = src >> 24;
    *(dst++) = src >> 16;
    *(dst++) = src >> 8;
    *dst = src;
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u64_be_to_byte(void *dst, uint64_t src)
{
    uint8_t *_dst = dst;
    *(dst++) = src >> 56;
    *(dst++) = src >> 48;
    *(dst++) = src >> 40;
    *(dst++) = src >> 32;
    *(dst++) = src >> 24;
    *(dst++) = src >> 16;
    *(dst++) = src >> 8;
    *dst = src;
}

#endif


//  cvt_uNN_le_to_byte series
CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u08_le_to_byte(void *dst, uint8_t src)
{
    *((uint8_t *)dst) = src;
}

#if defined __BIG_ENDIAN__ && defined __NO_ALIGN_REQ__

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u16_le_to_byte(void *dst, uint16_t src)
{
    *((uint16_t *)dst) = cvt_u16_endian(src);
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u32_le_to_byte(void *dst, uint32_t src)
{
    *((uint32_t *)dst) = cvt_u32_endian(src);
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u64_le_to_byte(void *dst, uint64_t src)
{
    *((uint64_t *)dst) = cvt_u64_endian(src);
}

#elif defined __LITTLE_ENDIAN__ && defined __NO_ALIGN_REQ__

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u16_le_to_byte(void *dst, uint16_t src)
{
    *((uint16_t *)dst) = src;
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u32_le_to_byte(void *dst, uint32_t src)
{
    *((uint32_t *)dst) = src;
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u64_le_to_byte(void *dst, uint64_t src)
{
    *((uint64_t *)dst) = src;
}

#else

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u16_le_to_byte(void *dst, uint16_t src)
{
    uint8_t *_dst = dst;
    *(dst++) = src;
    *dst = src >> 8;
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u32_le_to_byte(void *dst, uint32_t src)
{
    uint8_t *_dst = dst;
    *(dst++) = src;
    *(dst++) = src >> 8;
    *(dst++) = src >> 16;
    *dst = src >> 24;
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_u64_le_to_byte(void *dst, uint64_t src)
{
    uint8_t *_dst = dst;
    *(dst++) = src;
    *(dst++) = src >> 8;
    *(dst++) = src >> 16;
    *(dst++) = src >> 24;
    *(dst++) = src >> 32;
    *(dst++) = src >> 40;
    *(dst++) = src >> 48;
    *dst = src >> 56;
}

#endif


//  cvt_uNN_endian series
CVT_INT_MEM_PREFIX uint8_t CVT_INT_MEM_API cvt_u08_endian(uint8_t src)
{
    return src;
}

CVT_INT_MEM_PREFIX uint16_t CVT_INT_MEM_API cvt_u16_endian(uint16_t src)
{
    return ((src & UINT16_C(0x00FF)) << 8) | ((src & UINT16_C(0xFF00)) >> 8);
}

CVT_INT_MEM_PREFIX uint32_t CVT_INT_MEM_API cvt_u32_endian(uint32_t src)
{
    src = ((src & UINT32_C(0x0000FFFF)) << 16)
        | ((src & UINT32_C(0xFFFF0000)) >> 16);
    src = ((src & UINT32_C(0x00FF00FF)) << 8)
        | ((src & UINT32_C(0xFF00FF00)) >> 8);
    return src;
}

CVT_INT_MEM_PREFIX uint64_t CVT_INT_MEM_API cvt_u64_endian(uint64_t src)
{
    src = ((src & UINT64_C(0x00000000FFFFFFFF)) << 32)
        | ((src & UINT64_C(0xFFFFFFFF00000000)) >> 32);
    src = ((src & UINT64_C(0x0000FFFF0000FFFF)) << 16)
        | ((src & UINT64_C(0xFFFF0000FFFF0000)) >> 16);
    src = ((src & UINT64_C(0x00FF00FF00FF00FF)) << 8)
        | ((src & UINT64_C(0xFF00FF00FF00FF00)) >> 8);

    return src;
}


//  cvt_bNN_endian series
CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_b08_endian(void *dst, const void *src)
{
    *((uint8_t *)dst) = *((const uint8_t *)src);
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_b16_endian(void *dst, const void *src)
{
    cvt_u16_le_to_byte(dst, cvt_byte_to_u16_be(src));
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_b32_endian(void *dst, const void *src)
{
    cvt_u32_le_to_byte(dst, cvt_byte_to_u32_be(src));
}

CVT_INT_MEM_PREFIX void CVT_INT_MEM_API cvt_b64_endian(void *dst, const void *src)
{
    cvt_u64_le_to_byte(dst, cvt_byte_to_u64_be(src));
}